#include "Booking_system.h"


//销毁
void Destory(PTicket_info& PT, PFiight_info& PF)
{
	free(PT->data);
	free(PF->data);
	PT->capacity = 0;
	PT->size = 0;
	PF->capacity = 0;
	PF->size = 0;
	free(PT);
	free(PF);
	
}


void menu()
{
	printf("\n\n\n");
	printf("\t\t-------------------------------------------------\n");
	printf("\t\t||              ----------------               ||\n");
	printf("\t\t||**************航天客运订票系统***************||\n");
	printf("\t\t||              ----------------               ||\n");
	printf("\t\t||                                             ||\n");
	printf("\t\t||~~~~~~~~~~~~~~~1.录入航班信息~~~~~~~~~~~~~~~~||\n");
	printf("\t\t||~~~~~~~~~~~~~~~2.删除航班信息~~~~~~~~~~~~~~~~||\n");
	printf("\t\t||~~~~~~~~~~~~~~~3.修改航班信息~~~~~~~~~~~~~~~~||\n");
	printf("\t\t||~~~~~~~~~~~~~~~4.查询航班信息~~~~~~~~~~~~~~~~||\n");
	printf("\t\t||~~~~~~~~~~~~~~~5.显示航班信息~~~~~~~~~~~~~~~~||\n");
	printf("\t\t||~~~~~~~~~~~~~~~6.订票~~~~~~~~~~~~~~~~~~~~~~~~||\n");
	printf("\t\t||~~~~~~~~~~~~~~~7.退票~~~~~~~~~~~~~~~~~~~~~~~~||\n");
	printf("\t\t||~~~~~~~~~~~~~~~8.退出系统~~~~~~~~~~~~~~~~~~~~||\n");
	printf("\t\t||                                             ||\n");
	printf("\t\t||*********************************************||\n");
}

void Init_Fiight_info(PFiight_info& PF)
{
	PF = (PFiight_info)malloc(sizeof(Fiight_info));
	PF->capacity = 4;
	PF->size = 0;
	PF->data = (PA_flight_info)malloc(sizeof(A_flight_info) * PF->capacity);
}

void Push_back(PFiight_info& PF)
{
	if (PF->capacity == PF->size)
	{
		//扩容
		PF->capacity *= 2;
		PA_flight_info newdata = (PA_flight_info)realloc(PF->data, sizeof(A_flight_info) * PF->capacity);
		
		assert(newdata);

		PF->data = newdata;

	}

	PA_flight_info PA = (PA_flight_info)malloc(sizeof(A_flight_info));
	Input(PA);
	PF->data[PF->size++] = *PA;
	bool check;
	if (PA->size == PA->capacity) check = true;
	else check = false;
	printf("录入成功\n");
	printf("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
	printf("航班编号\t|出发地点\t|目的地\t\t|起飞时间\t\t|到达时间\t\t|票价\t   |折扣    |容量   |人数\t  |是否满仓\t|一等余票\t|二等余票\t|三等余票|\n");

	PrintOne(PA);
	//航班信息修改，重新写入文件
	Save_flight_info(PF);

	free(PA);
}

void Input(PA_flight_info& PA)
{
	printf("请输入要录入的航班信息\n");
	printf("请输入航班编号：");
	scanf("%s", PA->number);
	printf("请输入起始地：");
	scanf("%s", PA->start_place);
	printf("请输入目标地：");
	scanf("%s", PA->final_destination);
	printf("请输入起飞时间：");
	scanf("%s", PA->start_time);
	printf("请输入到达时间：");
	scanf("%s", PA->end_time);
	printf("请输入票价：");
	scanf("%lf", &(PA->price));
	printf("请输入折扣：");
	scanf("%lf", &(PA->discount));
	printf("请输入航班容量：");
	scanf("%d", &(PA->capacity));
	printf("请输入航班人数：");
	scanf("%d", &(PA->size));
	printf("请输入一等余票：");
	scanf("%d", &(PA->lessrank1));
	printf("请输入二等余票：");
	scanf("%d", &(PA->lessrank2));
	printf("请输入三等余票：");
	scanf("%d", &(PA->lessrank3));
}

//编号查找
PA_flight_info Find_number(PFiight_info& PF)
{
	int flag = 0;
	char fnumber[20];
	printf("请输入要查找的编号\n");
	scanf("%s", fnumber);
	PA_flight_info cur = NULL;
	for (int i = 0; i < PF->size; i++)
	{
		if (strcmp(fnumber, PF->data[i].number) == 0)
		{
			printf("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
			printf("航班编号\t|出发地点\t|目的地\t\t|起飞时间\t\t|到达时间\t\t|票价\t   |折扣    |容量   |人数\t  |是否满仓\t|一等余票\t|二等余票\t|三等余票|\n");
			cur = &(PF->data[i]);
			PrintOne(cur);
			flag = 1;
			break;
		}
	}
	if (flag) printf("查找成功\n");
	else printf("没有该航班\n");

	return cur;
}

//起点查找
void Find_start_place(PFiight_info& PF)
{
	int flag = 0;
	char fstart_place[20];
	printf("请输入要查找的起点\n");
	scanf("%s", fstart_place);
	for (int i = 0; i < PF->size; i++)
	{
		if (strcmp(fstart_place, PF->data[i].start_place) == 0)
		{
			if (flag == 0) {
				printf("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
				printf("航班编号\t|出发地点\t|目的地\t\t|起飞时间\t\t|到达时间\t\t|票价\t   |折扣    |容量   |人数\t  |是否满仓\t|一等余票\t|二等余票\t|三等余票|\n");
			}
			PA_flight_info cur = &(PF->data[i]);
			PrintOne(cur);
			flag = 1;
		}
	}
	if (flag) printf("查找成功\n");
	else printf("没有该航班\n");
}

//终点查找
void Find_final_destination(PFiight_info& PF)
{
	int flag = 0;
	char ffinal_destination[20];
	printf("请输入要查找的终点\n");
	scanf("%s", ffinal_destination);
	for (int i = 0; i < PF->size; i++)
	{
		if (strcmp(ffinal_destination, PF->data[i].final_destination) == 0)
		{
			if (flag == 0) {
				printf("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
				printf("航班编号\t|出发地点\t|目的地\t\t|起飞时间\t\t|到达时间\t\t|票价\t   |折扣    |容量   |人数\t  |是否满仓\t|一等余票\t|二等余票\t|三等余票|\n");
			}
			PA_flight_info cur = &(PF->data[i]);
			PrintOne(cur);
			flag = 1;
		}
	}
	if (flag) printf("查找成功\n");
	else printf("没有该航班\n");
}

void Find(PFiight_info& PF)
{
	printf("请输入要查找的方式\n");
	printf("…………------------------…………\n");
	printf("…………1.根据航班编号查找…………\n");
	printf("…………2.根据航班起点查找…………\n");
	printf("…………3.根据航班终点查找…………\n");
	printf("…………------------------…………\n");

	int x;
	scanf("%d", &x);
	if (x == 1)
	{
		Find_number(PF);

	}
	else if (x == 2)
	{
		Find_start_place(PF);
	}
	else if(x == 3)
	{
		Find_final_destination(PF);
	}
	else
	{
		printf("输入错误, 无效操作\n");
	}


}

void Print(PFiight_info& PF)
{
	printf("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
	printf("航班编号\t|出发地点\t|目的地\t\t|起飞时间\t\t|到达时间\t\t|票价\t   |折扣    |容量   |人数\t  |是否满仓\t|一等余票\t|二等余票\t|三等余票|\n");
	printf("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
	for (int i = 0; i < PF->size; i++)
	{
		//判断是否满仓
		bool check;
		if (PF->data[i].size == PF->data[i].capacity) check = true;
		else check = false;
		printf("%-16s|%-15s|%-15s|%-23s|%-23s|%-10.2lf|%-8.2lf|%-8d|%-12d|%s\t\t|%d\t\t|%d\t\t|%d\t |\n", PF->data[i].number,
			PF->data[i].start_place, PF->data[i].final_destination, PF->data[i].start_time, PF->data[i].end_time, PF->data[i].price,
			PF->data[i].discount, PF->data[i].capacity, PF->data[i].size, check ? "是" : "否", PF->data[i].lessrank1,
			PF->data[i].lessrank2, PF->data[i].lessrank3);
		printf("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");

	}
}

void PrintOne(PA_flight_info& PA)
{
	//判断是否满仓
	bool check;
	if (PA->size == PA->capacity) check = true;
	else check = false;
	printf("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
	printf("%-16s|%-15s|%-15s|%-23s|%-23s|%-10.2lf|%-8.2lf|%-8d|%-12d|%s\t\t|%d\t\t|%d\t\t|%d\t |\n", PA->number,
		PA->start_place, PA->final_destination, PA->start_time, PA->end_time, PA->price,
		PA->discount, PA->capacity, PA->size, check ? "是" : "否",PA->lessrank1, PA->lessrank2, PA->lessrank3);
	printf("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");

}

//修改
void Modifi(PFiight_info& PF)
{
	//根据航班编号找到航班进行修改信息
	PA_flight_info cur = Find_number(PF);
	if (cur == NULL)
	{
		printf("编号输入错误\n");
		return;
	}
	//修改什么信息
	printf("\t\t-------------------------------------------------\n");
	printf("\t\t||              ----------------               ||\n");
	printf("\t\t||**************航班信息修改功能***************||\n");
	printf("\t\t||              ----------------               ||\n");
	printf("\t\t||                                             ||\n");
	printf("\t\t||~~~~~~~~~~~1.航班编号  2.起飞时间~~~~~~~~~~~~||\n");
	printf("\t\t||~~~~~~~~~~~3.到达时间  4. 起飞地点~~~~~~~~~~~||\n");
	printf("\t\t||~~~~~~~~~~~5.到达地点  6.价格~~~~~~~~~~~~~~~~||\n");
	printf("\t\t||~~~~~~~~~~~7.折扣     8.座位数~~~~~~~~~~~~~~~||\n");
	printf("\t\t||                                             ||\n");
	printf("\t\t||*********************************************||\n");

	int x;
	scanf("%d", &x);
	switch (x)
	{
	case 1:
		printf("请输入要改为什么：");
		scanf("%s", cur->number);
		break;
	case 2:
		printf("请输入要改为什么：");
		scanf("%s", cur->start_time);
		break;
	case 3:
		printf("请输入要改为什么：");
		scanf("%s", cur->end_time);
		break;
	case 4:
		printf("请输入要改为什么：");
		scanf("%s", cur->start_place);
		break;
	case 5:
		printf("请输入要改为什么：");
		scanf("%s", cur->final_destination);
		break;
	case 6:
		printf("请输入要改为什么：");
		scanf("%s", cur->price);
		break;
	case 7:
		printf("请输入要改为什么：");
		scanf("%s", cur->discount);
		break;
	case 8:
		printf("请输入要改为什么：");
		scanf("%s", cur->capacity);
		break;
	}
	printf("修改成功\n");

	//航班信息修改，重新写入文件
	Save_flight_info(PF);
	
}

void Delete(PFiight_info& PF)
{
	printf("请输入要删除的航班编号\n");
	char fnumber[20];
	scanf("%s", fnumber);
	//找到要删除的下标
	int pos = -1;
	for (int i = 0; i < PF->size; i++)
	{
		if (strcmp(fnumber, PF->data[i].number) == 0)
		{
			pos = i;
			break;
		}
	}
	if (pos == -1)
	{
		printf("输入错误\n");
		return;
	}

	//向前覆盖，size--
	PF->size--;
	for (int i = pos; pos < PF->size; pos++)
	{
		PF->data[i] = PF->data[i + 1];
	}

	printf("删除成功\n");

	//航班信息修改，重新写入文件
	Save_flight_info(PF);


}



//航班信息输入到文件（文件名默认为bookinfsystem_flight_info）
void Save_flight_info(PFiight_info& PF)
{
	FILE* fp;
	int n = PF->size;
	char filename[100] = "bookinfsystem_flight_info";
	//断言
	assert(fp = fopen(filename, "w"));
	fprintf(fp, "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");

	fprintf(fp, "航班编号\t|出发地点\t|目的地\t\t|起飞时间\t\t|到达时间\t\t|票价\t   |折扣    |容量   |人数\t  |是否满仓\t|一等余票\t|二等余票\t|三等余票|\n");

	fprintf(fp,"--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");


	for (int i = 0; i < n; i++)
	{
		bool check;
		if (PF->data[i].size == PF->data[i].capacity) check = true;
		else check = false;
		fprintf(fp, "%-16s|%-15s|%-15s|%-23s|%-23s|%-10.2lf|%-8.2lf|%-8d|%-12d|%s\t\t|%d\t\t|%d\t\t|%d\t |\n", PF->data[i].number,
			PF->data[i].start_place, PF->data[i].final_destination, PF->data[i].start_time, PF->data[i].end_time, PF->data[i].price,
			PF->data[i].discount, PF->data[i].capacity, PF->data[i].size, check ? "是" : "否", PF->data[i].lessrank1,
			PF->data[i].lessrank2, PF->data[i].lessrank3);
		fprintf(fp, "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");

	}
	//关闭文件
	fclose(fp);
}

//订票信息输入到文件（文件名默认为bookinfsystem_ticket_info）
void Save_ticket_info(PTicket_info& PT)
{
	FILE* fp;
	int n = PT->size;
	char filename[100] = "bookinfsystem_ticket_info";
	//断言
	assert(fp = fopen(filename, "w"));


	for (int i = 0; i < n; i++)
	{
		//打印每一个订票信息到指定文件

		fprintf(fp, "姓名\t\t证件号\t\t\t订单编号\t\t订票时间\t\t座位编号\t\t座位等级\n");

		fprintf(fp, "%s\t\t%s\t\t%s\t\t\t%s\t\t%s\t\t%s\n", PT->data[i].name, PT->data[i].cus_number,
			PT->data[i].order_number, PT->data[i].time, PT->data[i].seat_number, PT->data[i].seat);
		bool check;
		if (PT->data[i].pinfo->size == PT->data[i].pinfo->capacity) check = true;
		else check = false;
		fprintf(fp, "航班信息:\n");
		fprintf(fp, "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
		fprintf(fp, "航班编号\t|出发地点\t|目的地\t\t|起飞时间\t\t|到达时间\t\t|票价\t   |折扣    |容量   |人数\t  |是否满仓\t|一等余票\t|二等余票\t|三等余票|\n");
		fprintf(fp, "%-16s|%-15s|%-15s|%-23s|%-23s|%-10.2lf|%-8.2lf|%-8d|%-12d|%s\t\t|%d\t\t|%d\t\t|%d\t |\n", PT->data[i].pinfo->number,
			PT->data[i].pinfo->start_place, PT->data[i].pinfo->final_destination, PT->data[i].pinfo->start_time, 
			PT->data[i].pinfo->end_time, PT->data[i].pinfo->price, PT->data[i].pinfo->discount, PT->data[i].pinfo->capacity,
			PT->data[i].pinfo->size, check ? "是" : "否", PT->data[i].pinfo->lessrank1,
			PT->data[i].pinfo->lessrank2, PT->data[i].pinfo->lessrank3);
		fprintf(fp, "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n\n\n");

	}
	//关闭文件
	fclose(fp);
}



//初始化订票顺序表
void Init_Ticket_info(PTicket_info& PT)
{
	PT = (PTicket_info)malloc(sizeof(Ticket_info));
	PT->capacity = 4;
	PT->size = 0;
	PT->data = (PA_ticket_info)malloc(sizeof(A_ticket_info) * PT->capacity);
}

//订票(就是插入信息)
void Push_back_t(PTicket_info& PT, PFiight_info& PF)
{
	if (PT->capacity == PT->size)
	{
		//扩容
		PT->capacity *= 2;
		PA_ticket_info newdata = (PA_ticket_info)realloc(PT->data, sizeof(A_ticket_info) * PT->capacity);

		assert(newdata);

		PT->data = newdata;

	}

	PA_ticket_info PA = (PA_ticket_info)malloc(sizeof(A_ticket_info));
	if (Input_t(PA, PF)) {
		PT->data[PT->size++] = *PA;
		printf("录入成功\n");
	}
	else
	{
		printf("您可以选择以下航班\n");
		//订票失败，匹配合适的航班， 座位足够，起始地点和目的地与原客户订单相同
		for (int i = 0; i < PF->size; i++)
		{
			if (strcmp(PA->pinfo->start_place, PF->data[i].start_place) == 0 &&
				strcmp(PA->pinfo->final_destination, PF->data[i].final_destination) == 0
				&& PF->data[i].size < PF->data[i].capacity)
			{
				printf("航班编号\t\t出发地点\t\t\t目的地\t起飞时间\t\t\t到达时间\t票价\t折扣\t容量\t人数\t是否满仓\t一等余票\t二等余票\t三等余票\n");
				//打印该航班的信息
				PA_flight_info cur = &(PF->data[i]);
				PrintOne(cur);
			}
		}
	}

	//信息修改，重新写入文件
	Save_flight_info(PF);
	Save_ticket_info(PT);

}

int Input_t(PA_ticket_info& PA, PFiight_info& PF)
{
	printf("请输入姓名\n");
	scanf("%s", PA->name);
	printf("请输入证件号\n");
	scanf("%s", PA->cus_number);
	printf("请输入订单编号\n");
	scanf("%s", PA->order_number);
	printf("请输入订票时间\n");
	scanf("%s", PA->time);
	printf("请输入座位编号\n");
	scanf("%s", PA->seat_number);
	printf("请输入几等（一等。二等，三等））\n");
	scanf("%s", PA->seat);
	printf("请输入航班编号\n");
	scanf("%s", PA->number);
	
	for (int i = 0; i < PF->size; i++)
	{
		if (strcmp(PA->number, PF->data[i].number) == 0)
		{
			PA->pinfo = &(PF->data[i]);
			//人数增加，修改相关航班信息
			if (strcmp(PA->seat, "一等") == 0)
			{
				if (PF->data[i].lessrank1 > 0)
					PF->data[i].lessrank1--;
				else
				{
					printf("没有了\n");
					return 0;
				}
			}
			else if (strcmp(PA->seat, "二等") == 0)
			{
				if (PF->data[i].lessrank2 > 0)
					PF->data[i].lessrank2--;
				else
				{
					printf("没有了\n");
					return 0;
				}
			}
			else
			{
				if (PF->data[i].lessrank3 > 0)
					PF->data[i].lessrank3--;
				else
				{
					printf("没有了\n");
					return 0;
				}
			}
			PA->pinfo->size--;

			return 1;
		}
	}
	//航班输入错误，返回0，订票失败
	printf("航班输入错误, 订票失败\n");
	return 0;
}

//退票(删除指定信息)
void Delete_t(PTicket_info& PT, PFiight_info& PF)
{
	printf("请输入要删除的订单编号\n");
	char fnumber[20];
	scanf("%s", fnumber);
	//找到要删除的下标
	int pos = -1;
	for (int i = 0; i < PT->size; i++)
	{
		if (strcmp(fnumber, PT->data[i].order_number) == 0)
		{
			pos = i;
			break;
		}
	}
	if (pos == -1)
	{
		printf("输入错误\n");
		return;
	}
	//座位加一  
	if (strcmp(PT->data[pos].seat, "一等"))
		PT->data[pos].pinfo->lessrank1++;
	if (strcmp(PT->data[pos].seat, "二等"))
		PT->data[pos].pinfo->lessrank2++;
	else
		PT->data[pos].pinfo->lessrank3++;

	//人数加一
	PT->data[pos].pinfo->size++;


	//向前覆盖，size--
	PT->size--;
	for (int i = pos; pos < PT->size; pos++)
	{
		PT->data[i] = PT->data[i + 1];
	}

	printf("退票成功\n");

	//信息修改，重新写入文件
	Save_flight_info(PF);
	Save_ticket_info(PT);

}